package com.motong.gongdan.controller.system.erp;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.motong.gongdan.config.ResponseData;
import com.motong.gongdan.config.auth.UserLoginToken;
import com.motong.gongdan.controller.system.ProduceController;
import com.motong.gongdan.entity.FormTableDetail;
import com.motong.gongdan.entity.Product;
import com.motong.gongdan.entity.Unit;
import com.motong.gongdan.service.ProductService;
import com.motong.gongdan.service.UnitService;
import com.motong.gongdan.vo.system.Erp.vo.EditSalesOrderReturnVo;
import com.motong.gongdan.vo.system.otherVo.EditSalesOrderProductVo;
import com.motong.gongdan.vo.system.otherVo.EditSalesOrderVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@Api(tags = "erp交互管理")
@RestController
@RequestMapping("/sys/erp")
public class ErpController {

    @Resource
    private ProductService productService;

    @Resource
    private UnitService unitService;

    @Resource
    private ProduceController produceController;

    @UserLoginToken
    @ApiOperation(value = "编辑销售订单")
    @PostMapping("/editSalesOrder")
    @Transactional(rollbackFor = Exception.class)
    public ResponseData<EditSalesOrderReturnVo> editSalesOrder(@RequestBody EditSalesOrderVo vo) {
        List<EditSalesOrderProductVo> salesOrderProductVo = vo.getSalesOrderProductVo();
        if (!CollectionUtils.isEmpty(salesOrderProductVo)) {
            Date currentDate = new Date();
            HashMap<String, String> productNameUnitNameMap = new HashMap<>(salesOrderProductVo.size());

            List<String> productNames = new ArrayList<>();
            List<String> unitNames = new ArrayList<>();
            salesOrderProductVo.forEach(i -> {
                productNames.add(i.getProductName().concat("[erp]"));
                productNames.add(i.getProductName());
                unitNames.add(i.getProductUnitName());
                productNameUnitNameMap.put(i.getProductName(), i.getProductUnitName());
            });
            List<Product> existProducts = productService.list(new LambdaQueryWrapper<Product>().in(Product::getName, productNames).eq(Product::getDelFlag, 0));
            Map<String, Product> productNameProductMap = new HashMap<>(salesOrderProductVo.size());
            Set<String> existProductNames = new HashSet<>();
            existProducts.forEach(i -> {
                String oriProductName = i.getName().replace("[erp]", "");
                existProductNames.add(oriProductName);
                productNameProductMap.put(oriProductName, i);
                productNameProductMap.put(i.getName(), i);
            });
            List<Unit> existUnits = unitService.list(new LambdaQueryWrapper<Unit>().in(Unit::getName, unitNames));
            Map<String, Integer> unitNameUnitIdMap = new HashMap<>(salesOrderProductVo.size());
            List<String> existUnitNames = new ArrayList<>();
            existUnits.forEach(i -> {
                existUnitNames.add(i.getName());
                unitNameUnitIdMap.put(i.getName(), i.getId());
            });

            List<Product> saveProductList = new ArrayList<>();
            List<Unit> saveUnitList = new ArrayList<>();

            salesOrderProductVo
                    .forEach(i -> {
                        if (!existProductNames.contains(i.getProductName())) {
                            Product product = new Product().setName(i.getProductName().concat("[erp]")).setAttribute(0).setSpecification(i.getModel())
                                    .setCode("CP".concat(i.getErpProductId()).concat("[erpId]")).setUnitPrice(BigDecimal.ZERO).setStock(BigDecimal.ZERO);
                            saveProductList.add(product);
                        }
                        if (!existUnitNames.contains(i.getProductUnitName())) {
                            Unit erpUnit = new Unit().setName(i.getProductUnitName()).setComment("erp同步创建单位");
                            saveUnitList.add(erpUnit);
                        }
                    });

            if (!CollectionUtils.isEmpty(saveUnitList)) {
                unitService.saveBatch(saveUnitList);
                saveUnitList.forEach(i -> unitNameUnitIdMap.put(i.getName(), i.getId()));
            }
            saveProductList.forEach(i -> {
                String oriProductName = i.getName().replace("[erp]", "");
                String unitName = productNameUnitNameMap.getOrDefault(oriProductName, "未知单位");
                Integer unitId = unitNameUnitIdMap.get(unitName);
                if (Objects.nonNull(unitId)) {
                    i.setUnitId(unitId);
                }
            });

            if (!CollectionUtils.isEmpty(saveProductList)) {
                productService.saveBatch(saveProductList);
                saveProductList.forEach(i -> productNameProductMap.put( i.getName().replace("[erp]", ""), i));
            }

            salesOrderProductVo.forEach(i -> {
                Product product = Optional.ofNullable(productNameProductMap.get(i.getProductName())).orElse(productNameProductMap.get(i.getProductName().concat("[erp]"))) ;
                if (Objects.nonNull(product)) {
                    i.setProductId(product.getId());
                }
                i.setCustomFieldVos(Collections.emptyList());
                i.setStartTime(Optional.ofNullable(i.getStartTime()).orElse(DateUtil.beginOfDay(currentDate)));
                i.setEndTime(Optional.ofNullable(i.getEndTime()).orElse(DateUtil.endOfDay(currentDate)));
            });
        }
        produceController.editSalesOrder(vo);
        // 处理完数据返回对应id

        EditSalesOrderReturnVo finalResData = new EditSalesOrderReturnVo().setSalesId(vo.getId());
        for (EditSalesOrderProductVo i : vo.getSalesOrderProductVo()) {
            FormTableDetail realData = i.getRealData();
            if (Objects.nonNull(realData)){
                Map<Long, Integer> erpIdDetailIdMap = Optional.ofNullable(finalResData.getErpDetailIdSalesDetailIdMap()).orElse(new HashMap<>());
                erpIdDetailIdMap.put(i.getDepotItemId(),realData.getId()) ;
            }
        }
        return ResponseData.success(finalResData);
    }


}
